package com.shenhaofeng.app.loader.list.component;

import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.widget.SwipeRefreshLayout;
import android.support.v7.widget.RecyclerView;
import android.view.ViewGroup;

import com.shenhaofeng.app.loader.list.DataSource;
import com.shenhaofeng.app.loader.list.Pager;
import com.shenhaofeng.app.loader.list.listener.OnBindDataListener;
import com.shenhaofeng.app.loader.list.listener.OnMoreStatusListener;
import com.shenhaofeng.app.loader.list.listener.OnRefreshStatusListener;
import com.shenhaofeng.app.loader.list.util.ScrollToBottomHelper;

import java.util.concurrent.Executor;

import rx.Subscriber;
import rx.android.schedulers.AndroidSchedulers;


/**
 * Created by Administrator on 2016/8/28.
 */
public class SwipeRecyclerComponent<D> extends RefreshComponent<D> {


    private ScrollToBottomHelper mScrollToBottomHelper;

    private RecyclerView.Adapter adapter;

    private OnMoreStatusListener<D> mOnMoreStatusListener;


    public SwipeRecyclerComponent(OnRefreshStatusListener<D> statusListener, RecyclerView.Adapter adapter, OnMoreStatusListener<D> mOnMoreStatusListener) {
        super(statusListener);
        this.adapter = adapter;
        this.mOnMoreStatusListener = mOnMoreStatusListener;
        mScrollToBottomHelper = new ScrollToBottomHelper();
        this.mOnMoreStatusListener = mOnMoreStatusListener;
        this.adapter = adapter;
    }


    public SwipeRecyclerComponent(Executor mExecutor, OnRefreshStatusListener<D> statusListener, RecyclerView.Adapter adapter, OnMoreStatusListener<D> mOnMoreStatusListener) {
        super(mExecutor, statusListener);
        this.adapter = adapter;
        this.mOnMoreStatusListener = mOnMoreStatusListener;
        mScrollToBottomHelper = new ScrollToBottomHelper();
        this.mOnMoreStatusListener = mOnMoreStatusListener;
        this.adapter = adapter;
    }


    public SwipeRecyclerComponent(Looper mLooper, OnRefreshStatusListener<D> statusListener, RecyclerView.Adapter adapter, OnMoreStatusListener<D> mOnMoreStatusListener) {
        super(mLooper, statusListener);
        this.adapter = adapter;
        this.mOnMoreStatusListener = mOnMoreStatusListener;
        mScrollToBottomHelper = new ScrollToBottomHelper();
        this.mOnMoreStatusListener = mOnMoreStatusListener;
        this.adapter = adapter;
    }


    public OnMoreStatusListener<D> getStatusHandler() {
        return mOnMoreStatusListener;
    }


    @Override
    protected void attach(@NonNull ViewGroup mRefreshLayout, @NonNull ViewGroup mDataLayout, @NonNull DataSource<D> mDataSource, @NonNull OnBindDataListener<D> listener) {
        super.attach(mRefreshLayout, mDataLayout, mDataSource, listener);
        RecyclerView recyclerView = (RecyclerView) mDataLayout;
        recyclerView.setAdapter(adapter);
        mScrollToBottomHelper.setup(recyclerView, new ScrollToBottomCallback());
    }


    protected RecyclerView getRecyclerView() {
        return (RecyclerView) getDataView();
    }


    /**
     * 默认刷新控件使用SwipeRefreshLayout，数据控件使用RecyclerView
     *
     * @param mRefreshLayout
     * @param mDataLayout
     * @return
     */
    @Override
    public boolean hasLoadView(ViewGroup mRefreshLayout, ViewGroup mDataLayout) {
        return super.hasLoadView(mRefreshLayout, mDataLayout) && mDataLayout instanceof RecyclerView;
    }


    @Override
    protected void onRefreshStart(SwipeRefreshLayout swipeRefreshLayout) {
        super.onRefreshStart(swipeRefreshLayout);
        mScrollToBottomHelper.setEventEnable(true);
    }


    @Override
    protected void onRefreshCompleted(SwipeRefreshLayout swipeRefreshLayout) {
        super.onRefreshCompleted(swipeRefreshLayout);
        mScrollToBottomHelper.setEventEnable(true);
    }


    @Override
    protected void onMore(ViewGroup mRefreshLayout, ViewGroup mDataLayout, final int page, int pageSize, DataSource<D> dDataSource, final OnBindDataListener<D> dataListener) {
        final RecyclerView recyclerView = (RecyclerView) mDataLayout;
        dDataSource.onRequestData(page, pageSize)
                .subscribeOn(getWorkScheduler())
                .observeOn(AndroidSchedulers.mainThread())
                .subscribe(new Subscriber<D>() {
                    @Override
                    public void onStart() {
                        recyclerView.post(new Runnable() {
                            @Override
                            public void run() {
                                getStatusHandler().onLoadStart(getRecyclerView(), adapter);
                            }
                        });
                    }


                    @Override
                    public void onCompleted() {
                        recyclerView.post(new Runnable() {
                            @Override
                            public void run() {
                                //记录下一页
                                getPageManager().nextPage();
                                getStatusHandler().onLoadCompleted(getRecyclerView(), adapter);
                                mScrollToBottomHelper.setEventEnable(true);
                            }
                        });
                    }


                    @Override
                    public void onError(final Throwable e) {
                        recyclerView.post(new Runnable() {
                            @Override
                            public void run() {
                                getStatusHandler().onLoadThrowable(getRecyclerView(), adapter, e);
                            }
                        });
                    }


                    @Override
                    public void onNext(final D data) {
                        recyclerView.post(new Runnable() {
                            @Override
                            public void run() {
                                getListener().onBindDataToAdapter(recyclerView, page, data);
                                getStatusHandler().onLoadSuccess(getRecyclerView(), adapter, data);
                            }
                        });
                    }
                });
    }


    class ScrollToBottomCallback implements ScrollToBottomHelper.Callback {

        @Override
        public void onScrollToBottom() {
            Pager pager = getPageManager();
            int nextPage = pager.peekNextPage();
            int pageSize = pager.getPageSize();
            onMore(getRefreshView(), getDataView(), nextPage, pageSize, getDataSource(), getListener());
        }
    }

}
